home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / tcpdump-3.0 / print-tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-15  |  7.7 KB  |  312 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-tcp.c,v 1.28 94/06/16 01:26:40 mccanne Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/types.h>
  30.  
  31. #include <netinet/in.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/ip.h>
  34. #include <netinet/ip_var.h>
  35. #include <netinet/tcp.h>
  36. #include <netinet/tcpip.h>
  37.  
  38. #include <stdio.h>
  39. #ifdef __STDC__
  40. #include <stdlib.h>
  41. #endif
  42. #include <unistd.h>
  43.  
  44. #include "interface.h"
  45. #include "addrtoname.h"
  46.  
  47. #ifndef TCPOPT_WSCALE
  48. #define    TCPOPT_WSCALE        3    /* window scale factor (rfc1072) */
  49. #endif
  50. #ifndef TCPOPT_SACKOK
  51. #define    TCPOPT_SACKOK        4    /* selective ack ok (rfc1072) */
  52. #endif
  53. #ifndef TCPOPT_SACK
  54. #define    TCPOPT_SACK        5    /* selective ack (rfc1072) */
  55. #endif
  56. #ifndef TCPOPT_ECHO
  57. #define    TCPOPT_ECHO        6    /* echo (rfc1072) */
  58. #endif
  59. #ifndef TCPOPT_ECHOREPLY
  60. #define    TCPOPT_ECHOREPLY    7    /* echo (rfc1072) */
  61. #endif
  62. #ifndef TCPOPT_TIMESTAMP
  63. #define TCPOPT_TIMESTAMP    8    /* timestamps (rfc1323) */
  64. #endif
  65. #ifndef TCPOPT_CC
  66. #define TCPOPT_CC        11    /* CC (rfc1644) */
  67. #endif
  68. #ifndef TCPOPT_CCNEW
  69. #define TCPOPT_CCNEW        12    /* CC (rfc1644) */
  70. #endif
  71. #ifndef TCPOPT_CCECHO
  72. #define TCPOPT_CCECHO        13    /* CC (rfc1644) */
  73. #endif
  74.  
  75. struct tha {
  76.     struct in_addr src;
  77.     struct in_addr dst;
  78.     u_int port;
  79. };
  80.  
  81. struct tcp_seq_hash {
  82.     struct tcp_seq_hash *nxt;
  83.     struct tha addr;
  84.     tcp_seq seq;
  85.     tcp_seq ack;
  86. };
  87.  
  88. #define TSEQ_HASHSIZE 919
  89.  
  90. static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
  91.  
  92.  
  93. void
  94. tcp_print(register const u_char *bp, register int length,
  95.       register const u_char *bp2)
  96. {
  97.     register const struct tcphdr *tp;
  98.     register const struct ip *ip;
  99.     register u_char flags;
  100.     register int hlen;
  101.     u_short sport, dport, win, urp;
  102.     u_int32 seq, ack;
  103.     u_char *data;
  104.  
  105.     tp = (struct tcphdr *)bp;
  106.     ip = (struct ip *)bp2;
  107.     if ((const u_char *)(tp + 1)  > snapend) {
  108.         printf("[|tcp]");
  109.         return;
  110.     }
  111.     if (length < sizeof(struct tcphdr)) {
  112.         (void)printf("truncated-tcp %d", length);
  113.         return;
  114.     }
  115.  
  116.     sport = ntohs(tp->th_sport);
  117.     dport = ntohs(tp->th_dport);
  118.     seq = ntohl(tp->th_seq);
  119.     ack = ntohl(tp->th_ack);
  120.     win = ntohs(tp->th_win);
  121.     urp = ntohs(tp->th_urp);
  122.  
  123.     (void)printf("%s.%s > %s.%s: ",
  124.         ipaddr_string(&ip->ip_src), tcpport_string(sport),
  125.         ipaddr_string(&ip->ip_dst), tcpport_string(dport));
  126.  
  127.     if (qflag) {
  128.         (void)printf("tcp %d", length - tp->th_off * 4);
  129.         return;
  130.     }
  131.     if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
  132.         if (flags & TH_SYN)
  133.             putchar('S');
  134.         if (flags & TH_FIN)
  135.             putchar('F');
  136.         if (flags & TH_RST)
  137.             putchar('R');
  138.         if (flags & TH_PUSH)
  139.             putchar('P');
  140.     } else
  141.         putchar('.');
  142.  
  143.     if (!Sflag && (flags & TH_ACK)) {
  144.         register struct tcp_seq_hash *th;
  145.         register int rev;
  146.         struct tha tha;
  147.         /*
  148.          * Find (or record) the initial sequence numbers for
  149.          * this conversation.  (we pick an arbitrary
  150.          * collating order so there's only one entry for
  151.          * both directions).
  152.          */
  153.         if (sport < dport ||
  154.             (sport == dport &&
  155.              ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
  156.             tha.src = ip->ip_src, tha.dst = ip->ip_dst;
  157.             tha.port = sport << 16 | dport;
  158.             rev = 0;
  159.         } else {
  160.             tha.src = ip->ip_dst, tha.dst = ip->ip_src;
  161.             tha.port = dport << 16 | sport;
  162.             rev = 1;
  163.         }
  164.  
  165.         for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
  166.              th->nxt; th = th->nxt)
  167.             if (!bcmp((char *)&tha, (char *)&th->addr,
  168.                   sizeof(th->addr)))
  169.                 break;
  170.  
  171.         if (!th->nxt || flags & TH_SYN) {
  172.             /* didn't find it or new conversation */
  173.             if (!th->nxt)
  174.                 th->nxt = (struct tcp_seq_hash *)
  175.                     calloc(1, sizeof (*th));
  176.             th->addr = tha;
  177.             if (rev)
  178.                 th->ack = seq, th->seq = ack - 1;
  179.             else
  180.                 th->seq = seq, th->ack = ack - 1;
  181.         } else {
  182.             if (rev)
  183.                 seq -= th->ack, ack -= th->seq;
  184.             else
  185.                 seq -= th->seq, ack -= th->ack;
  186.         }
  187.     }
  188.     hlen = tp->th_off * 4;
  189.     length -= hlen;
  190.     if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
  191.         (void)printf(" %u:%lu(%d)", seq, seq + length, length);
  192.     if (flags & TH_ACK)
  193.         (void)printf(" ack %u", ack);
  194.  
  195.     (void)printf(" win %d", win);
  196.  
  197.     if (flags & TH_URG)
  198.         (void)printf(" urg %d", urp);
  199.     /*
  200.      * Handle any options.
  201.      */
  202.     if ((hlen -= sizeof(struct tcphdr)) > 0) {
  203.         register const u_char *cp = (const u_char *)tp + sizeof(*tp);
  204.         int i, l;
  205.         char ch = '<';
  206.  
  207.         putchar(' ');
  208.         while (--hlen >= 0) {
  209.             putchar(ch);
  210.             switch (*cp++) {
  211.             case TCPOPT_EOL:
  212.                 (void)printf("eol");
  213.                 break;
  214.             case TCPOPT_NOP:
  215.                 (void)printf("nop");
  216.                 break;
  217.             case TCPOPT_MAXSEG:
  218.                 (void)printf("mss %d", cp[1] << 8 | cp[2]);
  219.                 if ((l = *cp) != 4)
  220.                     (void)printf("[len %d]", l);
  221.                 cp += l-1;
  222.                 hlen -= l-1;
  223.                 break;
  224.             case TCPOPT_WSCALE:
  225.                 (void)printf("wscale %d", cp[1]);
  226.                 if ((l = *cp) != 3)
  227.                     (void)printf("[len %d]", l);
  228.                 cp += l-1;
  229.                 hlen -= l-1;
  230.                 break;
  231.             case TCPOPT_SACKOK:
  232.                 (void)printf("sackOK");
  233.                 if ((l = *cp) != 2)
  234.                     (void)printf("[len %d]", l);
  235.                 cp += l-1;
  236.                 hlen -= l-1;
  237.                 break;
  238.             case TCPOPT_ECHO:
  239.                 (void)printf("echo %u",
  240.                          cp[1] << 24 | cp[2] << 16 |
  241.                          cp[3] << 8 | cp[4]);
  242.                 if ((l = *cp) != 6)
  243.                     (void)printf("[len %d]", l);
  244.                 cp += l-1;
  245.                 hlen -= l-1;
  246.                 break;
  247.             case TCPOPT_ECHOREPLY:
  248.                 (void)printf("echoreply %u",
  249.                          cp[1] << 24 | cp[2] << 16 |
  250.                          cp[3] << 8 | cp[4]);
  251.                 if ((l = *cp) != 6)
  252.                     (void)printf("[len %d]", l);
  253.                 cp += l-1;
  254.                 hlen -= l-1;
  255.                 break;
  256.             case TCPOPT_TIMESTAMP:
  257.                 (void)printf("timestamp %u %u",
  258.                          cp[1] << 24 | cp[2] << 16 |
  259.                          cp[3] << 8 | cp[4],
  260.                          cp[5] << 24 | cp[6] << 16 |
  261.                          cp[7] << 8 | cp[8]);
  262.                 if ((l = *cp) != 10)
  263.                     (void)printf("[len %d]", l);
  264.                 cp += l-1;
  265.                 hlen -= l-1;
  266.                 break;
  267.             case TCPOPT_CC:
  268.                 (void)printf("CC %u",
  269.                          cp[1] << 24 | cp[2] << 16 |
  270.                          cp[3] << 8 | cp[4]);
  271.                 if ((l = *cp) != 6)
  272.                     (void)printf("[len %d]", l);
  273.                 cp += l-1;
  274.                 hlen -= l-1;
  275.                 break;
  276.             case TCPOPT_CCNEW:
  277.                 (void)printf("CCnew %u",
  278.                          cp[1] << 24 | cp[2] << 16 |
  279.                          cp[3] << 8 | cp[4]);
  280.                 if ((l = *cp) != 6)
  281.                     (void)printf("[len %d]", l);
  282.                 cp += l-1;
  283.                 hlen -= l-1;
  284.                 break;
  285.             case TCPOPT_CCECHO:
  286.                 (void)printf("CCecho %u",
  287.                          cp[1] << 24 | cp[2] << 16 |
  288.                          cp[3] << 8 | cp[4]);
  289.                 if ((l = *cp) != 6)
  290.                     (void)printf("[len %d]", l);
  291.                 cp += l-1;
  292.                 hlen -= l-1;
  293.                 break;
  294.             default:
  295.                 (void)printf("opt-%d:", cp[-1]);
  296.                 for (i = *cp++ - 2, hlen -= i + 1; i > 0; --i)
  297.                     (void)printf("%02x", *cp++);
  298.                 break;
  299.             }
  300.             ch = ',';
  301.         }
  302.         putchar('>');
  303.     }
  304.  
  305.     data = ((char *)tp+(tp->th_off *4));
  306.     if (Dflag && length > 0) {
  307.         printf("\n\tData (%d): ", length);
  308.         fflush(stdout);
  309.         data_print(data, (length > (snapend-data)) ? (snapend-data) : length);
  310.     }
  311. }
  312.